<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript核心概念</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3b82f6',
                        secondary: '#10b981',
                        dark: '#1e293b',
                        light: '#f8fafc'
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                        mono: ['Consolas', 'Monaco', 'monospace']
                    }
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .code-block {
                @apply bg-gray-900 text-gray-100 p-4 rounded-lg font-mono text-sm overflow-x-auto my-4 transition-all;
            }
            .demo-output {
                @apply bg-gray-50 border border-gray-200 p-4 rounded-lg min-h-[80px] my-4;
            }
            .section-card {
                @apply bg-white rounded-xl shadow-md p-6 mb-8 transition-all duration-300 hover:shadow-lg;
            }
            .method-list {
                @apply grid grid-cols-1 md:grid-cols-2 gap-3 my-4;
            }
            .method-item {
                @apply bg-blue-50 p-3 rounded border border-blue-100 hover:border-primary transition-colors;
            }
            .concept-item {
                @apply mb-6 pb-6 border-b border-gray-100 last:border-0 last:mb-0 last:pb-0;
            }
            .nav-item {
                @apply py-2 px-3 rounded hover:bg-primary/10 transition-colors cursor-pointer;
            }
            .nav-item.active {
                @apply bg-primary/10 font-medium text-primary;
            }
            .dom-demo-box {
                @apply border-2 border-dashed border-gray-300 p-4 my-4 min-h-[100px];
            }
            .dom-demo-element {
                @apply bg-blue-100 p-2 m-1 inline-block rounded;
            }
        }
    </style>
</head>

<body class="bg-gray-50">
    <!-- 顶部导航栏 -->
    <header class="bg-primary text-white shadow-md sticky top-0 z-50">
        <div class="container mx-auto px-4 py-4">
            <div class="flex justify-between items-center">
                <h1 class="text-xl md:text-2xl font-bold flex items-center">
                    <i class="fa fa-code mr-2"></i>JavaScript 核心概念
                </h1>
                <div class="hidden md:flex items-center space-x-4">
                    <button id="toggleTheme" class="p-2 rounded-full hover:bg-white/20 transition-colors">
                        <i class="fa fa-moon-o"></i>
                    </button>
                    <button id="toggleToc" class="p-2 rounded-full hover:bg-white/20 transition-colors md:hidden">
                        <i class="fa fa-bars"></i>
                    </button>
                </div>
            </div>
        </div>
    </header>

    <!-- 主内容区 -->
    <div class="container mx-auto px-4 py-6 flex flex-col md:flex-row gap-6 max-w-7xl">
        <!-- 侧边栏导航 -->
        <aside id="toc"
            class="hidden md:block w-full md:w-64 lg:w-72 shrink-0 h-[calc(100vh-6rem)] sticky top-20 overflow-y-auto bg-white rounded-xl shadow-sm p-4">
            <h2 class="text-lg font-bold mb-4 pb-2 border-b border-gray-200">目录</h2>
            <nav class="space-y-1 text-gray-700">
                <div class="nav-item active" data-target="intro">
                    <i class="fa fa-info-circle mr-2"></i>简介
                </div>
                <div class="nav-item" data-target="basic-syntax">
                    <i class="fa fa-code mr-2"></i>1. 语法基础
                </div>
                <div class="pl-4 nav-item" data-target="variables">
                    <i class="fa fa-angle-right mr-1"></i>变量声明
                </div>
                <div class="pl-4 nav-item" data-target="data-types">
                    <i class="fa fa-angle-right mr-1"></i>数据类型
                </div>
                <div class="pl-4 nav-item" data-target="type-conversion">
                    <i class="fa fa-angle-right mr-1"></i>类型转换
                </div>
                <div class="pl-4 nav-item" data-target="operators">
                    <i class="fa fa-angle-right mr-1"></i>运算符
                </div>

                <div class="nav-item" data-target="control-flow">
                    <i class="fa fa-random mr-2"></i>2. 流程控制
                </div>
                <div class="pl-4 nav-item" data-target="conditionals">
                    <i class="fa fa-angle-right mr-1"></i>条件语句
                </div>
                <div class="pl-4 nav-item" data-target="loops">
                    <i class="fa fa-angle-right mr-1"></i>循环语句
                </div>

                <div class="nav-item" data-target="data-structures">
                    <i class="fa fa-database mr-2"></i>3. 数据结构
                </div>
                <div class="pl-4 nav-item" data-target="strings">
                    <i class="fa fa-angle-right mr-1"></i>字符串
                </div>
                <div class="pl-4 nav-item" data-target="arrays">
                    <i class="fa fa-angle-right mr-1"></i>数组
                </div>
                <div class="pl-4 nav-item" data-target="objects">
                    <i class="fa fa-angle-right mr-1"></i>对象
                </div>

                <div class="nav-item" data-target="functions">
                    <i class="fa fa-cogs mr-2"></i>4. 函数
                </div>
                <div class="pl-4 nav-item" data-target="function-basics">
                    <i class="fa fa-angle-right mr-1"></i>函数基础
                </div>
                <div class="pl-4 nav-item" data-target="function-advanced">
                    <i class="fa fa-angle-right mr-1"></i>函数进阶
                </div>

                <div class="nav-item" data-target="dom">
                    <i class="fa fa-html5 mr-2"></i>5. DOM操作
                </div>
                <div class="pl-4 nav-item" data-target="dom-basics">
                    <i class="fa fa-angle-right mr-1"></i>DOM基础
                </div>
                <div class="pl-4 nav-item" data-target="dom-manipulation">
                    <i class="fa fa-angle-right mr-1"></i>DOM操作
                </div>
                <div class="pl-4 nav-item" data-target="dom-events">
                    <i class="fa fa-angle-right mr-1"></i>事件处理
                </div>

                <div class="nav-item" data-target="async">
                    <i class="fa fa-clock-o mr-2"></i>6. 异步编程
                </div>
            </nav>
        </aside>

        <!-- 主要内容 -->
        <main class="flex-1">
            <!-- 简介部分 -->
            <section id="intro" class="section-card">
                <h2 class="text-2xl font-bold mb-6 text-gray-800">JavaScript 简介</h2>
                <div class="prose max-w-none">
                    <p class="text-gray-700 mb-4">
                        JavaScript 是一种轻量级的、解释型的编程语言，最初为网页交互而设计，现在已成为全栈开发的核心技术之一。
                        它可以运行在浏览器中，也可以通过 Node.js 运行在服务器端。
                    </p>
                </div>
            </section>

            <!-- 1. 语法基础 -->
            <section id="basic-syntax" class="section-card">
                <h2 class="text-2xl font-bold mb-6 text-gray-800">1. 语法基础</h2>

                <!-- 变量声明 -->
                <div id="variables" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">变量声明</h3>
                    <p class="text-gray-700 mb-4">
                        变量是存储信息的容器，JavaScript 提供了三种声明变量的方式，各有不同的特性和适用场景：
                    </p>
                    <ul class="list-disc pl-5 text-gray-600 mb-4 space-y-2">
                        <li><code class="bg-gray-100 px-1 rounded">var</code>：函数级作用域，存在变量提升，可重复声明（不推荐使用）</li>
                        <li><code class="bg-gray-100 px-1 rounded">let</code>：块级作用域，无变量提升，不可重复声明，可修改</li>
                        <li><code class="bg-gray-100 px-1 rounded">const</code>：块级作用域，声明时必须赋值，不可修改（常量）</li>
                    </ul>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="variablesCode">
// var 声明（不推荐）
var a = 10;
var a = 20; // 允许重复声明
console.log("var 声明:", a);

// let 声明
let b = "hello";
b = "world"; // 允许修改
console.log("let 声明:", b);
// let b = "again"; // 错误：不允许重复声明

// const 声明（常量）
const c = true;
console.log("const 声明:", c);
// c = false; // 错误：不允许修改
// const d; // 错误：声明时必须赋值

// 块级作用域示例
if (true) {
    var x = 100; // 函数级作用域，外部可访问
    let y = 200; // 块级作用域，外部不可访问
    const z = 300; // 块级作用域，外部不可访问
}
console.log("var 在块外访问:", x);
// console.log(y); // 错误：y 未定义
// console.log(z); // 错误：z 未定义</pre>

                    <button onclick="runCode('variablesCode', 'variablesOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="variablesOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- 数据类型 -->
                <div id="data-types" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">数据类型</h3>
                    <p class="text-gray-700 mb-4">
                        JavaScript 是弱类型语言，变量类型可以动态变化。主要分为原始类型（值类型）和引用类型两大类：
                    </p>

                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
                        <div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
                            <h4 class="font-medium text-gray-800 mb-2">原始类型（值类型）</h4>
                            <ul class="list-disc pl-5 text-gray-600 space-y-1">
                                <li><code class="bg-gray-100 px-1 rounded">string</code>：字符串（如 "hello"）</li>
                                <li><code class="bg-gray-100 px-1 rounded">number</code>：数字（如 42、3.14）</li>
                                <li><code class="bg-gray-100 px-1 rounded">boolean</code>：布尔值（true 或 false）</li>
                                <li><code class="bg-gray-100 px-1 rounded">null</code>：空值（表示无值）</li>
                                <li><code class="bg-gray-100 px-1 rounded">undefined</code>：未定义（变量声明未赋值）</li>
                            </ul>
                        </div>
                        <div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
                            <h4 class="font-medium text-gray-800 mb-2">引用类型</h4>
                            <ul class="list-disc pl-5 text-gray-600 space-y-1">
                                <li><code class="bg-gray-100 px-1 rounded">object</code>：对象</li>
                                <li><code class="bg-gray-100 px-1 rounded">array</code>：数组</li>
                                <li><code class="bg-gray-100 px-1 rounded">function</code>：函数</li>
                            </ul>
                        </div>
                    </div>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="dataTypesCode">
// 原始类型
const str = "Hello World"; // string
const num = 42; // number
const bool = true; // boolean
const n = null; // null
let und; // undefined

// 引用类型
const obj = { name: "JavaScript" }; // object
const arr = [1, 2, 3]; // array
const func = function() { return "Hello"; }; // function

// 检测类型
console.log("str 类型:", typeof str);
console.log("num 类型:", typeof num);
console.log("bool 类型:", typeof bool);
console.log("n 类型:", typeof n); // 注意：null 会返回 "object"
console.log("und 类型:", typeof und);
console.log("obj 类型:", typeof obj);
console.log("arr 类型:", typeof arr); // 数组也是 object
console.log("arr 是否为数组:", Array.isArray(arr));
console.log("func 类型:", typeof func);</pre>

                    <button onclick="runCode('dataTypesCode', 'dataTypesOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="dataTypesOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- 类型转换 -->
                <div id="type-conversion" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">类型转换</h3>
                    <p class="text-gray-700 mb-4">
                        JavaScript 会自动进行类型转换（隐式转换），也可以通过函数手动转换（显式转换）。理解类型转换规则对于避免 bug 非常重要。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="typeConversionCode">
// 隐式转换（自动发生）
console.log("隐式转换示例：");
console.log("10" + 2); // "102"（字符串拼接）
console.log("10" - 2); // 8（字符串转为数字）
console.log("10" * 2); // 20（字符串转为数字）
console.log(10 + true); // 11（true 转为 1）
console.log(10 + false); // 10（false 转为 0）
console.log(10 + null); // 10（null 转为 0）
console.log(10 + undefined); // NaN（undefined 转为 NaN）

// 显式转换（手动转换）
console.log("\n显式转换示例：");
// 转为数字
console.log(Number("123")); // 123
console.log(Number("123abc")); // NaN（无法完全转换）
console.log(parseInt("123.45")); // 123（整数）
console.log(parseFloat("123.45")); // 123.45（浮点数）

// 转为字符串
console.log(String(123)); // "123"
console.log(123.toString()); // "123"

// 转为布尔值
console.log(Boolean(0)); // false
console.log(Boolean(1)); // true
console.log(Boolean("")); // false
console.log(Boolean("hello")); // true
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean({})); // true（所有对象转为布尔值都是 true）
console.log(Boolean([])); // true（数组也是对象）</pre>

                    <button onclick="runCode('typeConversionCode', 'typeConversionOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="typeConversionOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- 运算符 -->
                <div id="operators" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">运算符</h3>
                    <p class="text-gray-700 mb-4">
                        运算符用于执行程序代码运算，JavaScript 提供了多种类型的运算符：
                    </p>

                    <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
                        <div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
                            <h4 class="font-medium text-gray-800 mb-2">基础运算符</h4>
                            <ul class="list-disc pl-5 text-gray-600 space-y-1">
                                <li><strong>算术运算符</strong>：+、-、*、/、%（取余）、++、--</li>
                                <li><strong>比较运算符</strong>：==、===、!=、!==、>、<、>=、<=< /li>
                                <li><strong>逻辑运算符</strong>：&&（与）、||（或）、!（非）</li>
                                <li><strong>赋值运算符</strong>：=、+=、-=、*=、/=、%=</li>
                            </ul>
                        </div>
                        <div class="bg-gray-50 p-4 rounded-lg border border-gray-200">
                            <h4 class="font-medium text-gray-800 mb-2">ES6+ 运算符</h4>
                            <ul class="list-disc pl-5 text-gray-600 space-y-1">
                                <li><strong>可选链运算符</strong>：?.（安全访问嵌套属性）</li>
                                <li><strong>空值合并运算符</strong>：??（处理默认值）</li>
                                <li><strong>扩展运算符</strong>：...（展开数组/对象）</li>
                                <li><strong>三元运算符</strong>：condition ? expr1 : expr2</li>
                            </ul>
                        </div>
                    </div>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="operatorsCode">
// 算术运算符
let a = 10, b = 3;
console.log("算术运算：");
console.log(a + b); // 13
console.log(a - b); // 7
console.log(a * b); // 30
console.log(a / b); // 3.333...
console.log(a % b); // 1（取余）
console.log(++a); // 11（先加后用）
console.log(b++); // 3（先用后加）
console.log(b); // 4

// 比较运算符
console.log("\n比较运算：");
console.log(a == 11); // true
console.log(a == "11"); // true（只比较值）
console.log(a === "11"); // false（比较值和类型）
console.log(a != 5); // true
console.log(a !== "11"); // true
console.log(a > b); // true

// 逻辑运算符
const x = true, y = false;
console.log("\n逻辑运算：");
console.log(x && y); // false（与）
console.log(x || y); // true（或）
console.log(!x); // false（非）

// 三元运算符
const age = 18;
const status = age >= 18 ? "成年人" : "未成年人";
console.log("\n三元运算：", status);

// 可选链运算符 (?.)
const user = {
    name: "张三",
    address: {
        city: "北京"
        // street 属性不存在
    }
};
console.log("\n可选链运算：");
console.log(user?.address?.city); // "北京"
console.log(user?.address?.street); // undefined（不报错）

// 空值合并运算符 (??)
const username = null;
const displayName = username ?? "匿名用户";
console.log("空值合并：", displayName); // "匿名用户"

// 扩展运算符 (...)
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log("扩展运算：", arr2); // [1, 2, 3, 4, 5]</pre>

                    <button onclick="runCode('operatorsCode', 'operatorsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="operatorsOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>
            </section>

            <!-- 2. 流程控制 -->
            <section id="control-flow" class="section-card">
                <h2 class="text-2xl font-bold mb-6 text-gray-800">2. 流程控制</h2>

                <!-- 条件语句 -->
                <div id="conditionals" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">条件语句</h3>
                    <p class="text-gray-700 mb-4">
                        条件语句用于根据不同条件执行不同的代码块，JavaScript 提供了多种条件判断方式：
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="conditionalsCode">
// if-else 语句
const score = 85;

if (score >= 90) {
    console.log("优秀");
} else if (score >= 80) {
    console.log("良好");
} else if (score >= 60) {
    console.log("及格");
} else {
    console.log("不及格");
}

// switch-case 语句
const day = 3;
let dayName;

switch (day) {
    case 1:
        dayName = "星期一";
        break;
    case 2:
        dayName = "星期二";
        break;
    case 3:
        dayName = "星期三";
        break;
    case 4:
        dayName = "星期四";
        break;
    case 5:
        dayName = "星期五";
        break;
    case 6:
        dayName = "星期六";
        break;
    case 7:
        dayName = "星期日";
        break;
    default:
        dayName = "无效的日期";
}
console.log("今天是：", dayName);

// 逻辑运算符的短路特性
const user = { name: "张三" };

// 等价于 if (user) { console.log(user.name) }
user && console.log("用户名称：", user.name);

// 为变量设置默认值
const username = null;
const displayName = username || "访客";
console.log("显示名称：", displayName);</pre>

                    <button onclick="runCode('conditionalsCode', 'conditionalsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="conditionalsOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- 循环语句 -->
                <div id="loops" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">循环语句</h3>
                    <p class="text-gray-700 mb-4">
                        循环语句用于重复执行一段代码，JavaScript 提供了多种循环方式以适应不同场景：
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="loopsCode">
// for 循环
console.log("for 循环：");
for (let i = 1; i <= 5; i++) {
    console.log("循环次数：", i);
}

// while 循环
console.log("\nwhile 循环：");
let count = 1;
while (count <= 3) {
    console.log("计数：", count);
    count++;
}

// do-while 循环（至少执行一次）
console.log("\ndo-while 循环：");
let num = 5;
do {
    console.log("数字：", num);
    num--;
} while (num > 5); // 条件为 false，但仍执行一次

// for-in 循环（遍历对象属性）
console.log("\nfor-in 循环：");
const person = { name: "张三", age: 25, city: "北京" };
for (let key in person) {
    console.log(key + ": " + person[key]);
}

// for-of 循环（遍历可迭代对象）
console.log("\nfor-of 循环：");
const fruits = ["苹果", "香蕉", "橙子"];
for (let fruit of fruits) {
    console.log("水果：", fruit);
}

// 循环控制语句
console.log("\n循环控制：");
for (let i = 1; i <= 10; i++) {
    if (i % 2 === 0) {
        continue; // 跳过偶数
    }
    if (i > 7) {
        break; // 当 i > 7 时跳出循环
    }
    console.log("奇数：", i);
}</pre>

                    <button onclick="runCode('loopsCode', 'loopsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="loopsOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>
            </section>

            <!-- 3. 数据结构 -->
            <section id="data-structures" class="section-card">
                <h2 class="text-2xl font-bold mb-6 text-gray-800">3. 数据结构</h2>

                <!-- 字符串 -->
                <div id="strings" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">字符串（String）</h3>
                    <p class="text-gray-700 mb-4">
                        字符串用于表示文本数据，在 JavaScript 中是不可变的（一旦创建就不能修改）。提供了丰富的方法用于字符串操作。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">常用方法速览：</h4>
                    <div class="method-list">
                        <div class="method-item"><strong>length</strong> - 获取字符串长度</div>
                        <div class="method-item"><strong>indexOf()</strong> - 查找子串首次出现位置</div>
                        <div class="method-item"><strong>includes()</strong> - 判断是否包含子串</div>
                        <div class="method-item"><strong>slice()</strong> - 截取子串</div>
                        <div class="method-item"><strong>toUpperCase()</strong> - 转为大写</div>
                        <div class="method-item"><strong>toLowerCase()</strong> - 转为小写</div>
                        <div class="method-item"><strong>trim()</strong> - 去除两端空白</div>
                        <div class="method-item"><strong>split()</strong> - 分割为数组</div>
                        <div class="method-item"><strong>replace()</strong> - 替换子串</div>
                        <div class="method-item"><strong>startsWith()</strong> - 判断是否以子串开头</div>
                    </div>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="stringsCode">
const str = "   Hello JavaScript World!   ";

// 基本属性
console.log("原始字符串:", str);
console.log("长度:", str.length);

// 查找与判断
console.log("是否包含 'JavaScript':", str.includes("JavaScript"));
console.log("'World' 首次出现位置:", str.indexOf("World"));
console.log("是否以 'Hello' 开头:", str.trimStart().startsWith("Hello"));
console.log("是否以 '!' 结尾:", str.trimEnd().endsWith("!"));

// 截取与提取
console.log("从索引 5 开始截取:", str.slice(5));
console.log("从索引 5 到 10 截取:", str.slice(5, 10));
console.log("最后 6 个字符:", str.slice(-6));

// 转换与修改
console.log("转为大写:", str.toUpperCase());
console.log("转为小写:", str.toLowerCase());
console.log("去除两端空白:", str.trim());
console.log("去除左侧空白:", str.trimStart());

// 分割与替换
console.log("按空格分割:", str.trim().split(" "));
console.log("替换 'JavaScript' 为 'JS':", str.replace("JavaScript", "JS"));
console.log("替换所有 'o' 为 '*':", str.replace(/o/g, "*"));

// 模板字符串（ES6+）
const name = "JavaScript";
const version = "ES6";
const template = `学习 ${name} ${version} 特性
这是多行字符串
第三行内容`;
console.log("\n模板字符串:");
console.log(template);</pre>

                    <button onclick="runCode('stringsCode', 'stringsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="stringsOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- 数组 -->
                <div id="arrays" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">数组（Array）</h3>
                    <p class="text-gray-700 mb-4">
                        数组用于存储多个值的有序集合，提供了大量方法用于数组操作，是 JavaScript 中最常用的数据结构之一。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">常用方法速览：</h4>
                    <div class="method-list">
                        <div class="method-item"><strong>push()</strong> - 末尾添加元素</div>
                        <div class="method-item"><strong>pop()</strong> - 删除末尾元素</div>
                        <div class="method-item"><strong>shift()</strong> - 删除首个元素</div>
                        <div class="method-item"><strong>unshift()</strong> - 开头添加元素</div>
                        <div class="method-item"><strong>map()</strong> - 映射为新数组</div>
                        <div class="method-item"><strong>filter()</strong> - 筛选元素</div>
                        <div class="method-item"><strong>reduce()</strong> - 聚合计算</div>
                        <div class="method-item"><strong>find()</strong> - 查找元素</div>
                        <div class="method-item"><strong>includes()</strong> - 判断是否包含</div>
                        <div class="method-item"><strong>sort()</strong> - 排序</div>
                    </div>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="arraysCode">
// 创建数组
const numbers = [1, 2, 3, 4, 5, 6];
const fruits = ["苹果", "香蕉", "橙子"];

// 基本属性
console.log("原始数组:", numbers);
console.log("数组长度:", numbers.length);

// 添加和删除元素
fruits.push("葡萄"); // 末尾添加
console.log("push 后:", fruits);

const lastFruit = fruits.pop(); // 删除末尾
console.log("pop 后:", fruits, "删除的元素:", lastFruit);

fruits.unshift("草莓"); // 开头添加
console.log("unshift 后:", fruits);

const firstFruit = fruits.shift(); // 删除开头
console.log("shift 后:", fruits, "删除的元素:", firstFruit);

// 数组遍历与转换
console.log("\n数组遍历:");
numbers.forEach((num, index) => {
    console.log(`索引 ${index}: ${num}`);
});

// map: 转换数组元素
const squared = numbers.map(num => num * num);
console.log("平方结果:", squared);

// filter: 筛选元素
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log("偶数:", evenNumbers);

// reduce: 聚合计算
const sum = numbers.reduce((total, num) => total + num, 0);
console.log("总和:", sum);

// 查找元素
const firstGreaterThan3 = numbers.find(num => num > 3);
console.log("第一个大于3的数:", firstGreaterThan3);

const hasBanana = fruits.includes("香蕉");
console.log("是否有香蕉:", hasBanana);

// 排序与反转
const sorted = [...numbers].sort((a, b) => b - a); // 降序排序
console.log("降序排序:", sorted);

const reversed = [...numbers].reverse();
console.log("反转数组:", reversed);

// 数组扁平化
const nestedArray = [1, [2, [3, [4]]]];
console.log("扁平化1层:", nestedArray.flat());
console.log("完全扁平化:", nestedArray.flat(Infinity));</pre>

                    <button onclick="runCode('arraysCode', 'arraysOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="arraysOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- 对象 -->
                <div id="objects" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">对象（Object）</h3>
                    <p class="text-gray-700 mb-4">
                        对象是键值对的集合，用于存储复杂数据。在 JavaScript 中，几乎所有事物都是对象。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="objectsCode">
// 创建对象
const person = {
    name: "张三",
    age: 25,
    isStudent: false,
    hobbies: ["阅读", "运动"],
    greet: function() {
        return `你好，我是${this.name}`;
    }
};

// 访问属性
console.log("姓名:", person.name);
console.log("年龄:", person["age"]); // 另一种访问方式
console.log("爱好:", person.hobbies[0]);
console.log("打招呼:", person.greet());

// 修改属性
person.age = 26;
person["isStudent"] = true;
console.log("修改后的年龄:", person.age);

// 添加新属性
person.city = "北京";
console.log("添加的城市属性:", person.city);

// 删除属性
delete person.isStudent;
console.log("删除 isStudent 后:", person);

// 遍历对象
console.log("\n遍历对象属性:");
// 获取所有键
const keys = Object.keys(person);
console.log("所有键:", keys);

// 获取所有值
const values = Object.values(person);
console.log("所有值:", values);

// 获取所有键值对
const entries = Object.entries(person);
console.log("所有键值对:", entries);

// 遍历键值对
entries.forEach(([key, value]) => {
    console.log(`${key}: ${value}`);
});

// 对象复制
const personCopy = { ...person }; // 浅拷贝
personCopy.name = "李四";
console.log("\n原始对象:", person.name);
console.log("复制对象:", personCopy.name);

// 对象合并
const contact = { phone: "123456", email: "test@example.com" };
const personWithContact = { ...person, ...contact };
console.log("合并后的对象:", personWithContact);

// 解构赋值
const { name, age, city = "未知城市" } = person;
console.log("\n解构赋值:", name, age, city);</pre>

                    <button onclick="runCode('objectsCode', 'objectsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="objectsOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>
            </section>

            <!-- 4. 函数 -->
            <section id="functions" class="section-card">
                <h2 class="text-2xl font-bold mb-6 text-gray-800">4. 函数</h2>

                <!-- 函数基础 -->
                <div id="function-basics" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">函数基础</h3>
                    <p class="text-gray-700 mb-4">
                        函数是执行特定任务的代码块，可重复调用，是 JavaScript 的核心概念之一。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="functionBasicsCode">
// 1. 函数声明
function add(a, b) {
    return a + b;
}

// 2. 函数表达式
const multiply = function(a, b) {
    return a * b;
};

// 3. 箭头函数（ES6+）
const subtract = (a, b) => a - b;

// 4. 带默认参数的函数
function greet(name = "访客") {
    return `你好，${name}！`;
}

// 5. 剩余参数（...）
function sum(...numbers) {
    return numbers.reduce((total, num) => total + num, 0);
}

// 调用函数
console.log("add(2, 3) =", add(2, 3));
console.log("multiply(2, 3) =", multiply(2, 3));
console.log("subtract(5, 2) =", subtract(5, 2));
console.log("greet() =", greet());
console.log("greet('张三') =", greet("张三"));
console.log("sum(1, 2, 3, 4) =", sum(1, 2, 3, 4));

// 函数作为参数（回调函数）
function processNumbers(a, b, callback) {
    return callback(a, b);
}

const result1 = processNumbers(10, 5, add);
const result2 = processNumbers(10, 5, multiply);
console.log("\nprocessNumbers 加:", result1);
console.log("processNumbers 乘:", result2);

// 函数作为返回值
function createMultiplier(factor) {
    return function(number) {
        return number * factor;
    };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log("\n翻倍:", double(5));
console.log("三倍:", triple(5));</pre>

                    <button onclick="runCode('functionBasicsCode', 'functionBasicsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="functionBasicsOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- 函数进阶 -->
                <div id="function-advanced" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">函数进阶</h3>
                    <p class="text-gray-700 mb-4">
                        JavaScript 函数有许多高级特性，如闭包、this 关键字、箭头函数与普通函数的区别等，理解这些概念对于编写高质量代码非常重要。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="functionAdvancedCode">
// 闭包示例
function outerFunction() {
    const outerVar = "我是外部变量";
    
    function innerFunction() {
        // 内部函数可以访问外部函数的变量
        console.log(outerVar);
    }
    
    return innerFunction;
}

const closure = outerFunction();
closure(); // 即使 outerFunction 已执行完毕，仍能访问 outerVar

// this 关键字
const person = {
    name: "张三",
    age: 25,
    sayHello: function() {
        // this 指向调用该方法的对象
        console.log(`你好，我是${this.name}`);
    },
    sayAge: function() {
        console.log(`我${this.age}岁了`);
    }
};

person.sayHello();
person.sayAge();

// this 绑定示例
function showThis() {
    console.log(this);
}

const obj = { name: "测试对象", show: showThis };
console.log("作为函数调用:");
showThis(); // 在浏览器中通常指向 window 对象

console.log("作为对象方法调用:");
obj.show(); // 指向 obj 对象

// 箭头函数与普通函数的区别
const arrowDemo = {
    value: "对象属性",
    normalFunction: function() {
        console.log("普通函数 this:", this.value);
        
        // 普通函数中的 this 会改变
        setTimeout(function() {
            console.log("普通函数 setTimeout:", this.value); // undefined
        }, 0);
        
        // 箭头函数中的 this 继承自上下文
        setTimeout(() => {
            console.log("箭头函数 setTimeout:", this.value); // "对象属性"
        }, 0);
    },
    arrowFunction: () => {
        // 箭头函数没有自己的 this，继承自父级
        console.log("箭头函数 this:", this.value); // undefined
    }
};

arrowDemo.normalFunction();
arrowDemo.arrowFunction();

// 函数绑定
const boundFunction = showThis.bind(obj);
console.log("绑定后的函数:");
boundFunction();</pre>

                    <button onclick="runCode('functionAdvancedCode', 'functionAdvancedOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="functionAdvancedOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>
            </section>

            <!-- 5. DOM操作 -->
            <section id="dom" class="section-card">
                <h2 class="text-2xl font-bold mb-6 text-gray-800">5. DOM操作</h2>
                <p class="text-gray-700 mb-6">
                    DOM（文档对象模型）是HTML和XML文档的编程接口，它将文档表示为节点树，使JavaScript能够动态访问和修改文档的内容、结构和样式。
                </p>

                <!-- DOM基础 -->
                <div id="dom-basics" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">DOM基础与选择元素</h3>
                    <p class="text-gray-700 mb-4">
                        DOM将HTML文档表示为节点树，每个元素、属性、文本都是树中的节点。要操作DOM，首先需要选择要操作的元素。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">常用选择方法：</h4>
                    <div class="method-list">
                        <div class="method-item"><strong>getElementById()</strong> - 通过ID选择元素</div>
                        <div class="method-item"><strong>getElementsByClassName()</strong> - 通过类名选择元素</div>
                        <div class="method-item"><strong>getElementsByTagName()</strong> - 通过标签名选择元素</div>
                        <div class="method-item"><strong>querySelector()</strong> - 通过CSS选择器选择第一个匹配元素</div>
                        <div class="method-item"><strong>querySelectorAll()</strong> - 通过CSS选择器选择所有匹配元素</div>
                    </div>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="domBasicsCode">
// DOM 加载完成后执行
document.addEventListener('DOMContentLoaded', function() {
    // 通过ID选择元素
    const demoTitle = document.getElementById('domDemoTitle');
    console.log('通过ID选择:', demoTitle);
    
    // 通过类名选择元素
    const demoItems = document.getElementsByClassName('dom-demo-element');
    console.log('通过类名选择:', demoItems);
    console.log('类名选择的第一个元素:', demoItems[0]);
    
    // 通过标签名选择元素
    const paragraphs = document.getElementsByTagName('p');
    console.log('通过标签名选择的段落数量:', paragraphs.length);
    
    // 通过CSS选择器选择第一个匹配元素
    const firstDemoItem = document.querySelector('.dom-demo-element');
    console.log('querySelector 选择:', firstDemoItem.textContent);
    
    // 通过CSS选择器选择所有匹配元素
    const allDemoItems = document.querySelectorAll('.dom-demo-element');
    console.log('querySelectorAll 选择的数量:', allDemoItems.length);
    
    // 遍历 querySelectorAll 返回的NodeList
    allDemoItems.forEach((item, index) => {
        console.log(`第${index+1}个元素:`, item.textContent);
    });
});</pre>

                    <div class="dom-demo-box" id="domBasicsDemo">
                        <h4 id="domDemoTitle" class="mb-3">DOM选择演示区域</h4>
                        <div class="dom-demo-element">元素 1</div>
                        <div class="dom-demo-element">元素 2</div>
                        <div class="dom-demo-element">元素 3</div>
                    </div>

                    <button onclick="runCode('domBasicsCode', 'domBasicsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="domBasicsOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- DOM操作 -->
                <div id="dom-manipulation" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">DOM修改与操作</h3>
                    <p class="text-gray-700 mb-4">
                        选择元素后，可以修改其内容、属性和样式，也可以创建新元素并添加到文档中，或删除现有元素。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">常用操作方法：</h4>
                    <div class="method-list">
                        <div class="method-item"><strong>textContent</strong> - 获取或设置元素的文本内容</div>
                        <div class="method-item"><strong>innerHTML</strong> - 获取或设置元素的HTML内容</div>
                        <div class="method-item"><strong>setAttribute()</strong> - 设置元素属性</div>
                        <div class="method-item"><strong>getAttribute()</strong> - 获取元素属性</div>
                        <div class="method-item"><strong>classList</strong> - 操作元素的类</div>
                        <div class="method-item"><strong>createElement()</strong> - 创建新元素</div>
                        <div class="method-item"><strong>appendChild()</strong> - 添加子元素</div>
                        <div class="method-item"><strong>removeChild()</strong> - 删除子元素</div>
                        <div class="method-item"><strong>style</strong> - 操作元素的内联样式</div>
                    </div>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="domManipulationCode">
// 重置演示区域
function resetManipulationDemo() {
    const demoArea = document.getElementById('manipulationDemo');
    demoArea.innerHTML = `
        <h4>DOM操作演示区域</h4>
        <div class="dom-demo-element" id="demoElement">原始内容</div>
        <div id="newElementsContainer"></div>
    `;
}

// 执行DOM操作
function manipulateDOM() {
    // 1. 修改内容
    const demoElement = document.getElementById('demoElement');
    demoElement.textContent = "修改后的文本内容";
    console.log("修改文本内容完成");
    
    // 2. 修改样式
    demoElement.style.color = "blue";
    demoElement.style.fontWeight = "bold";
    console.log("修改样式完成");
    
    // 3. 修改类
    demoElement.classList.add("bg-yellow-100");
    demoElement.classList.remove("bg-blue-100");
    console.log("修改类完成");
    
    // 4. 创建新元素
    const newElement = document.createElement('div');
    newElement.textContent = "新创建的元素";
    newElement.className = "dom-demo-element bg-green-100";
    newElement.setAttribute("data-id", "new-1");
    
    // 5. 添加新元素到文档
    const container = document.getElementById('newElementsContainer');
    container.appendChild(newElement);
    console.log("添加新元素完成");
    
    // 6. 创建多个元素
    const fruits = ["苹果", "香蕉", "橙子"];
    fruits.forEach((fruit, index) => {
        const fruitElement = document.createElement('div');
        fruitElement.textContent = fruit;
        fruitElement.className = "dom-demo-element bg-orange-100";
        container.appendChild(fruitElement);
    });
    console.log("添加多个元素完成");
}

// 先重置再操作
resetManipulationDemo();
manipulateDOM();</pre>

                    <div class="dom-demo-box" id="manipulationDemo">
                        <h4>DOM操作演示区域</h4>
                        <div class="dom-demo-element" id="demoElement">原始内容</div>
                        <div id="newElementsContainer"></div>
                    </div>

                    <div class="flex gap-2">
                        <button onclick="runCode('domManipulationCode', 'domManipulationOutput')"
                            class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                            <i class="fa fa-play mr-1"></i> 运行代码
                        </button>
                        <button
                            onclick="resetManipulationDemo(); document.getElementById('domManipulationOutput').textContent = '点击\"
                            运行代码\"查看结果...'"
                            class="bg-gray-200 text-gray-800 px-4 py-2 rounded-lg hover:bg-gray-300 transition-colors">
                            <i class="fa fa-refresh mr-1"></i> 重置演示
                        </button>
                    </div>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="domManipulationOutput">
                        点击"运行代码"查看结果...
                    </div>
                </div>

                <!-- DOM事件 -->
                <div id="dom-events" class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">DOM事件处理</h3>
                    <p class="text-gray-700 mb-4">
                        事件是用户与网页交互时发生的动作（如点击、鼠标移动、键盘输入等）。JavaScript可以监听这些事件并执行相应的代码。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">常用事件类型：</h4>
                    <div class="method-list">
                        <div class="method-item"><strong>click</strong> - 鼠标点击元素</div>
                        <div class="method-item"><strong>dblclick</strong> - 鼠标双击元素</div>
                        <div class="method-item"><strong>mouseover</strong> - 鼠标移到元素上</div>
                        <div class="method-item"><strong>mouseout</strong> - 鼠标从元素移开</div>
                        <div class="method-item"><strong>keydown</strong> - 按下键盘按键</div>
                        <div class="method-item"><strong>keyup</strong> - 释放键盘按键</div>
                        <div class="method-item"><strong>input</strong> - 输入字段内容变化</div>
                        <div class="method-item"><strong>submit</strong> - 表单提交</div>
                        <div class="method-item"><strong>load</strong> - 页面或图像加载完成</div>
                    </div>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="domEventsCode">
// 确保DOM加载完成
document.addEventListener('DOMContentLoaded', function() {
    // 获取演示元素
    const eventBox = document.getElementById('eventBox');
    const clickCountElement = document.getElementById('clickCount');
    const messageElement = document.getElementById('eventMessage');
    const inputField = document.getElementById('eventInput');
    const colorButtons = document.querySelectorAll('.color-btn');
    
    // 点击计数器
    let clickCount = 0;
    
    // 1. 点击事件
    eventBox.addEventListener('click', function() {
        clickCount++;
        clickCountElement.textContent = clickCount;
        showMessage('盒子被点击了！');
    });
    
    // 2. 鼠标悬停和离开事件
    eventBox.addEventListener('mouseover', function() {
        this.style.transform = 'scale(1.05)';
        showMessage('鼠标移到盒子上了');
    });
    
    eventBox.addEventListener('mouseout', function() {
        this.style.transform = 'scale(1)';
        showMessage('鼠标离开了盒子');
    });
    
    // 3. 键盘事件
    inputField.addEventListener('input', function() {
        showMessage(`输入的内容: ${this.value}`);
    });
    
    // 4. 按钮点击事件（多个元素）
    colorButtons.forEach(button => {
        button.addEventListener('click', function() {
            const color = this.getAttribute('data-color');
            eventBox.style.backgroundColor = color;
            showMessage(`颜色已改为 ${color}`);
        });
    });
    
    // 显示消息的辅助函数
    function showMessage(text) {
        messageElement.textContent = text;
        // 3秒后清除消息
        setTimeout(() => {
            if (messageElement.textContent === text) {
                messageElement.textContent = '';
            }
        }, 3000);
    }
    
    console.log('事件监听器已设置完成');
});</pre>

                    <div class="dom-demo-box" id="eventsDemo">
                        <h4>事件处理演示区域</h4>
                        <div id="eventBox"
                            class="w-full h-32 bg-blue-100 flex items-center justify-center my-4 cursor-pointer transition-all">
                            点击我或把鼠标移到我上面
                        </div>
                        <p>点击次数: <span id="clickCount" class="font-bold">0</span></p>
                        <p id="eventMessage" class="text-primary font-medium"></p>
                        <div class="mt-4">
                            <input type="text" id="eventInput" placeholder="在这里输入内容..." class="border p-2 rounded">
                        </div>
                        <div class="mt-4">
                            <button class="color-btn px-3 py-1 m-1 bg-red-200 rounded" data-color="#fecaca">红色</button>
                            <button class="color-btn px-3 py-1 m-1 bg-green-200 rounded"
                                data-color="#d1fae5">绿色</button>
                            <button class="color-btn px-3 py-1 m-1 bg-blue-200 rounded" data-color="#bfdbfe">蓝色</button>
                        </div>
                    </div>

                    <button onclick="runCode('domEventsCode', 'domEventsOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 启动事件监听
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="domEventsOutput">
                        点击"启动事件监听"后，尝试与演示区域交互（点击、鼠标悬停、输入文本等）
                    </div>
                </div>
            </section>

            <!-- 6. 异步编程 -->
            <section id="async" class="section-card">
                <h2 class="text-2xl font-bold mb-6 text-gray-800">6. 异步编程</h2>
                <p class="text-gray-700 mb-4">
                    JavaScript 是单线程语言，异步编程是处理耗时操作（如网络请求、定时器）的关键技术，避免程序阻塞。
                </p>

                <!-- 异步编程基础 -->
                <div class="concept-item">
                    <h3 class="text-xl font-semibold mb-4 text-gray-800">异步编程方式</h3>
                    <p class="text-gray-700 mb-4">
                        JavaScript 提供了多种异步编程方式，从回调函数到 Promise，再到 async/await，逐步简化了异步代码的编写。
                    </p>

                    <h4 class="font-semibold text-gray-700 mb-2">示例代码：</h4>
                    <pre class="code-block" id="asyncCode">
// 1. 回调函数（Callback）
function fetchDataCallback(callback) {
    console.log("开始获取数据...");
    // 模拟网络请求延迟
    setTimeout(() => {
        const data = { id: 1, name: "回调函数数据" };
        callback(null, data); // 成功时调用
        // callback(new Error("获取数据失败"), null); // 失败时调用
    }, 1000);
}

console.log("===== 回调函数示例 =====");
fetchDataCallback((error, data) => {
    if (error) {
        console.error("错误:", error.message);
        return;
    }
    console.log("获取到的数据:", data);
});

// 2. Promise
function fetchDataPromise() {
    console.log("\n===== Promise 示例 =====");
    console.log("开始获取数据...");
    return new Promise((resolve, reject) => {
        // 模拟网络请求延迟
        setTimeout(() => {
            const success = true; // 控制成功/失败
            if (success) {
                const data = { id: 2, name: "Promise 数据" };
                resolve(data); // 成功
            } else {
                reject(new Error("获取数据失败")); // 失败
            }
        }, 1500);
    });
}

// 使用 Promise
fetchDataPromise()
    .then(data => {
        console.log("获取到的数据:", data);
        return { ...data, processed: true }; // 可以返回新数据供下一个 then 使用
    })
    .then(processedData => {
        console.log("处理后的数据:", processedData);
    })
    .catch(error => {
        console.error("错误:", error.message);
    })
    .finally(() => {
        console.log("Promise 操作完成（无论成功或失败都会执行）");
    });

// 3. async/await（Promise 的语法糖）
async function fetchDataAsyncAwait() {
    console.log("\n===== async/await 示例 =====");
    console.log("开始获取数据...");
    
    try {
        // 模拟网络请求延迟
        await new Promise(resolve => setTimeout(resolve, 2000));
        
        const success = true; // 控制成功/失败
        if (success) {
            const data = { id: 3, name: "async/await 数据" };
            return data;
        } else {
            throw new Error("获取数据失败");
        }
    } catch (error) {
        console.error("错误:", error.message);
        throw error; // 可以将错误继续抛出
    }
}

// 使用 async/await
(async () => {
    try {
        const data = await fetchDataAsyncAwait();
        console.log("获取到的数据:", data);
    } catch (error) {
        // 处理错误
    } finally {
        console.log("async/await 操作完成");
    }
})();</pre>

                    <button onclick="runCode('asyncCode', 'asyncOutput')"
                        class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-colors">
                        <i class="fa fa-play mr-1"></i> 运行代码
                    </button>

                    <h4 class="font-semibold text-gray-700 mt-4 mb-2">运行结果：</h4>
                    <div class="demo-output" id="asyncOutput">
                        点击"运行代码"查看结果（注意观察执行顺序和延迟）...
                    </div>
                </div>
            </section>
        </main>
    </div>

    <script>
        // 运行代码函数
        function runCode(codeId, outputId) {
            const codeElement = document.getElementById(codeId);
            const outputElement = document.getElementById(outputId);
            const code = codeElement.textContent;

            // 重写console.log
            const originalConsoleLog = console.log;
            outputElement.textContent = '';

            console.log = function (...args) {
                // 将参数转换为字符串
                const message = args.map(arg => {
                    if (typeof arg === 'object' && arg !== null) {
                        return JSON.stringify(arg, null, 2);
                    }
                    return arg.toString();
                }).join(' ');

                // 添加到输出区域
                outputElement.textContent += message + '\n';

                // 保持原始功能
                originalConsoleLog.apply(console, args);
            };

            try {
                // 执行代码
                new Function(code)();
            } catch (error) {
                outputElement.textContent += '错误: ' + error.message + '\n';
                console.error(error);
            } finally {
                // 恢复原始console.log
                console.log = originalConsoleLog;
                // 滚动到输出区域
                outputElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            }
        }

        // 导航功能
        document.querySelectorAll('.nav-item').forEach(item => {
            item.addEventListener('click', function () {
                // 移除所有active类
                document.querySelectorAll('.nav-item').forEach(navItem => {
                    navItem.classList.remove('active');
                });
                // 给当前点击项添加active类
                this.classList.add('active');

                // 滚动到目标区域
                const targetId = this.getAttribute('data-target');
                const targetElement = document.getElementById(targetId);
                if (targetElement) {
                    targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' });

                    // 在移动设备上点击导航后隐藏侧边栏
                    if (window.innerWidth < 768) {
                        document.getElementById('toc').classList.add('hidden');
                    }
                }
            });
        });

        // 移动端目录切换
        document.getElementById('toggleToc').addEventListener('click', function () {
            const toc = document.getElementById('toc');
            toc.classList.toggle('hidden');
        });

        // 主题切换功能
        document.getElementById('toggleTheme').addEventListener('click', function () {
            const body = document.body;
            const icon = this.querySelector('i');

            body.classList.toggle('bg-gray-900');
            body.classList.toggle('bg-gray-50');

            document.querySelectorAll('.section-card').forEach(card => {
                card.classList.toggle('bg-gray-800');
                card.classList.toggle('bg-white');
                card.classList.toggle('text-white');
                card.classList.toggle('text-gray-800');
            });

            if (icon.classList.contains('fa-moon-o')) {
                icon.classList.remove('fa-moon-o');
                icon.classList.add('fa-sun-o');
            } else {
                icon.classList.remove('fa-sun-o');
                icon.classList.add('fa-moon-o');
            }
        });

        // 页面加载完成后执行
        document.addEventListener('DOMContentLoaded', function () {
            // 初始化演示区域
            if (typeof resetManipulationDemo === 'function') {
                resetManipulationDemo();
            }
        });
    </script>
</body>

</html>